package de.szut.scene.scenes;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.util.Log;
import android.view.View;
import de.szut.database.DatabaseHelper;
import de.szut.entity.Country;
import de.szut.entity.OperatingSystem;
import de.szut.entity.User;
import de.szut.fragments.WorldMenuTabManager;
import de.szut.fragments.dialogs.GameLostDialog;
import de.szut.fragments.dialogs.GamePausedDialog;
import de.szut.fragments.dialogs.GameWonDialog;
import de.szut.interfaces.GameDialogListener;
import de.szut.interfaces.GameEventListener;
import de.szut.logic.Logic;
import de.szut.logic.ModifierStore;
import de.szut.main.GameActivity;
import de.szut.scene.helper.*;
import de.szut.timer.Timer;
import de.szut.util.Settings;
import org.andengine.engine.camera.Camera;
import org.andengine.engine.camera.ZoomCamera;
import org.andengine.engine.camera.hud.HUD;
import org.andengine.engine.handler.timer.ITimerCallback;
import org.andengine.engine.handler.timer.TimerHandler;
import org.andengine.entity.scene.IOnSceneTouchListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.scene.background.Background;
import org.andengine.entity.scene.menu.item.TextMenuItem;
import org.andengine.entity.sprite.ButtonSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.entity.sprite.batch.SpriteBatch;
import org.andengine.input.touch.TouchEvent;
import org.andengine.input.touch.detector.PinchZoomDetector;
import org.andengine.input.touch.detector.ScrollDetector;
import org.andengine.input.touch.detector.SurfaceScrollDetector;
import org.andengine.opengl.util.GLState;
import org.andengine.util.color.Color;

import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;
import java.util.StringTokenizer;

/**
 * Created by dzebcuks on 22.08.13.
 */
public class GameScene extends BaseScene implements PinchZoomDetector.IPinchZoomDetectorListener, IOnSceneTouchListener, ScrollDetector.IScrollDetectorListener, ButtonSprite.OnClickListener, GameEventListener, GameDialogListener {

    private static final int VIRUS_BTN_TAG = 0;
    private static final int WORLD_BTN_TAG = 1;
    private static float factor_max = 2.5f;
    private static float zoomMIN = 0.4f;
    private static float zoomMED = 0.7f;
    private static float zoomMAX = 1f;
    private static float factorZoomMIN = 0.4f;
    //View
    private Sprite gameMapClick;
    private Sprite gameMap;
    private Sprite gameMapInvisible;
    private Sprite hudBackground;
    private ButtonSprite hudVirusBtn;
    private ButtonSprite hudWorldBtn;
    private Sprite hudInfectedView;
    private Sprite hudControlledView;
    private Sprite hudCountryView;
    private Sprite hudResearchView;
    private HUD gameHud;
    private View abilityMenu;
    private View worldMenu;
    private TextMenuItem selectedCountryTxt;
    private TextMenuItem selectedInfectedUserTxt;
    private TextMenuItem selectedControlledUserTxt;
    private TextMenuItem researchProgressTxt;
    private SurfaceScrollDetector scrollDetector;
    private PinchZoomDetector pinchZoomDetector;
    //classes
    private ModifierStore modifierStore;
    private Country selectedCountry;
    private DatabaseHelper helper;
    private ZoomCamera zoomCamera;
    private Logic logic;
    private Timer timer;
    private InfectedDotPool infectedDotPool;
    private NewInfectionPool newInfectionPool;
    private GamePausedDialog pausedDialog;
    private GameWonDialog wonDialog;
    private GameLostDialog lostDialog;
    private StorageHelper storageHelper;
    //Values
    private float pinchZoomFactor;
    private boolean sceneIsTouchable = true;
    private HashMap<String, ArrayList<String>> countryPixeleMap;
    private HashMap<String, SpriteBatch> countrieBatches;
    private HashMap<String, ArrayList<Sprite>> drawnInfectedDots = new HashMap<String, ArrayList<Sprite>>();
    private HashMap<String, String> countryCenterPoints;
    private boolean timeIsRunning = false;
    private int infectedUserOfCurrentCountry;
    private int controlledUserOfCurrentCountry;
    NumberFormat formatter = new DecimalFormat("###,###,###,###.##");
    WorldMenuTabManager tabManager = ((GameActivity) GameScene.this.activity).getWorldMenuGenerator().getTabManager();

    public GameScene() {
    }

    @Override
    public void createScene() {
        logic = Logic.getInstance(this.activity);
        logic.setGameEventListener(this);
        this.prepareZoomCamera();
        this.scrollDetector = new SurfaceScrollDetector(this);
        this.pinchZoomDetector = new PinchZoomDetector(this);
        this.helper = DatabaseHelper.getInstance(this.activity);
        this.setBackground(new Background(Color.CYAN));
        createGameMapClick();
        createGameMap();
        createGameHUD();
        abilityMenu = resourcesManager.getActivity().getAbilityMenu();
        worldMenu = resourcesManager.getActivity().getWorldMenu();
        countryPixeleMap = resourcesManager.getCountryPixelMap();
        countrieBatches = resourcesManager.getCountrieBatches();
        countryCenterPoints = resourcesManager.getCountryCenterPoints();
        infectedDotPool = new InfectedDotPool(resourcesManager.getInfectedDot(), vbom);
        newInfectionPool = new NewInfectionPool(resourcesManager.getNewInfectedCountryIcon(), vbom);
        storageHelper = resourcesManager.getStorageHelper();
        initializeDialogs();
    }

    @Override
    public void onBackKeyPressed() {
        if (abilityMenu.getVisibility() == View.VISIBLE) {
            this.abilityMenu.post(new Runnable() {
                @Override
                public void run() {
                    GameScene.this.abilityMenu.setVisibility(View.GONE);
                    sceneIsTouchable = true;
                }
            });
        }
        if (worldMenu.getVisibility() == View.VISIBLE) {
            this.worldMenu.post(new Runnable() {
                @Override
                public void run() {
                    GameScene.this.worldMenu.setVisibility(View.GONE);
                    sceneIsTouchable = true;
                }
            });
        }
        if (worldMenu.getVisibility() == View.GONE && abilityMenu.getVisibility() == View.GONE) {
            showPauseDialog();
        }

    }

    @Override
    public SceneType getSceneType() {
        return SceneType.SCENE_GAME;
    }

    @Override
    public void disposeScene() {

    }

    private void showPauseDialog() {
        if (!pausedDialog.isVisible()) {
            if (timeIsRunning) {
                pauseTimer();
            }
            this.setSceneIsTouchable(false);
            pausedDialog.show(resourcesManager.getFragmentManager(), "pauseDlg");
        }
    }

    private void showLostDialog() {
        if (timeIsRunning) {
            pauseTimer();
        }
        this.setSceneIsTouchable(false);
        lostDialog.show(resourcesManager.getFragmentManager(), "lostDlg");
    }

    private void showWonDialog() {
        if (timeIsRunning) {
            pauseTimer();
        }
        this.setSceneIsTouchable(false);
        wonDialog.show(resourcesManager.getFragmentManager(), "wonDlg");
    }

    private void initializeDialogs() {
        this.pausedDialog = GamePausedDialog.newInstance(this, logic);
        this.wonDialog = GameWonDialog.newInstance(this);
        this.lostDialog = GameLostDialog.newInstance(this);
    }

    private void createGameMapClick() {
        gameMapClick = new Sprite(0, 0, resourcesManager.getGameRegionClick(), vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }

            @Override
            public boolean onAreaTouched(TouchEvent pSceneTouchEvent, float pointX, float pointY) {
                if (sceneIsTouchable) {
                    if (pSceneTouchEvent.getAction() == TouchEvent.ACTION_DOWN) {
                        pointX *= factorZoomMIN;
                        pointY *= factorZoomMIN;
                        int argbColor = GameScene.this.resourcesManager.getBackgroundBitmap().getPixel((int) (pointX), (int) (pointY));
                        Log.i("1337_COLOR", Integer.toString(argbColor));
                        GameScene.this.selectedCountry = GameScene.this.helper.getCountryDao().getCountryByColor(argbColor);
                        if (selectedCountry != null) {
                            setCurrentSelectedCountryInHud(selectedCountry.getName());
                            setInfectedAndControlledUserfromSelectedCountry(selectedCountry);
                            if (logic.gameHasStarted() == false) {
                                GameScene.this.populateInfectedUser(selectedCountry);
                                logic.infectCountry(selectedCountry);
                                setupTimerHandler();
                            }
                        } else {
                            setCurrentSelectedCountryInHud(activity.getResources().getString(de.szut.splasher.R.string.world));
                            setInfectedAndControlledUserfromSelectedCountry(selectedCountry);
                        }
                    }
                }
                return super.onAreaTouched(pSceneTouchEvent, pointX, pointY);    //To change body of overridden methods use File | Settings | File Templates.

            }
        };
        gameMapClick.setPosition((Settings.RESOLUTION_WIDTH * 0.5f) - (this.resourcesManager.getGameRegionClick().getWidth() * 0.5f), (Settings.RESOLUTION_HEIGHT * 0.5f) - (this.resourcesManager.getGameRegionClick().getHeight() * 0.5f));
        gameMapClick.setCullingEnabled(true);
        this.registerTouchArea(gameMapClick);
        this.setTouchAreaBindingOnActionDownEnabled(true);
        this.setOnSceneTouchListener(this);
        this.attachChild(gameMapClick);

    }

    public void createGameMap() {
        gameMap = new Sprite(0, 0, this.resourcesManager.getGameRegion(), vbom) {
            @Override
            protected void preDraw(GLState pGLState, Camera pCamera) {
                super.preDraw(pGLState, pCamera);
                pGLState.enableDither();
            }
        };
        gameMap.setPosition((Settings.RESOLUTION_WIDTH * 0.5f) - (this.resourcesManager.getGameRegion().getWidth() * 0.5f), (Settings.RESOLUTION_HEIGHT * 0.5f) - (this.resourcesManager.getGameRegion().getHeight() * 0.5f));
        gameMap.setCullingEnabled(true);
        this.attachChild(gameMap);
    }

    public void createGameHUD() {
        gameHud = new HUD();
        hudBackground = createHudBackground();
        hudVirusBtn = createHudVirusBtn();
        hudVirusBtn.setOnClickListener(this);
        hudWorldBtn = createHudWorldBtn();
        hudWorldBtn.setOnClickListener(this);
        hudCountryView = createHudCountryView();
        hudInfectedView = createHudInfectedView();
        hudControlledView = createHudControlledView();
        hudResearchView = createHudResearchView();
        gameHud.attachChild(hudBackground);
        gameHud.attachChild(hudVirusBtn);
        gameHud.attachChild(hudWorldBtn);
        gameHud.attachChild(hudInfectedView);
        gameHud.attachChild(hudControlledView);
        gameHud.attachChild(hudCountryView);
        gameHud.attachChild(hudResearchView);
        gameHud.setPosition(this.getScaleCenterX(), Settings.RESOLUTION_HEIGHT - 100);
        gameHud.registerTouchArea(hudWorldBtn);
        gameHud.registerTouchArea(hudVirusBtn);
        gameHud.registerTouchArea(hudBackground);
        gameHud.setCullingEnabled(true);
        this.zoomCamera.setHUD(gameHud);
    }


    private Sprite createHudBackground() {
        Sprite background = new Sprite(0, 0, this.resourcesManager.getHud_bg(), vbom);
        background.setPosition((Settings.RESOLUTION_WIDTH * 0.5f) - (background.getWidth() * 0.5f), (Settings.RESOLUTION_HEIGHT * 0.5f) - (background.getHeight() * 0.5f));
        background.setCullingEnabled(true);
        return background;
    }

    private ButtonSprite createHudVirusBtn() {
        ButtonSprite btn = new ButtonSprite(resourcesManager.getHud_button().getWidth(), resourcesManager.getHud_button().getHeight(), this.resourcesManager.getHud_button(), vbom);
        btn.setTag(VIRUS_BTN_TAG);
        btn.setCullingEnabled(true);
        btn.setPosition(10, 40);
        TextMenuItem virusBtnTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlack(), activity.getResources().getString(de.szut.splasher.R.string.virus), vbom);
        virusBtnTxt.setPosition(btn.getScaleCenterX() - (virusBtnTxt.getWidth() / 2), btn.getScaleCenterY() - (virusBtnTxt.getHeight() / 2));
        btn.attachChild(virusBtnTxt);
        return btn;
    }

    private ButtonSprite createHudWorldBtn() {
        ButtonSprite btn = new ButtonSprite(resourcesManager.getHud_button().getWidth(), resourcesManager.getHud_button().getHeight(), this.resourcesManager.getHud_button(), vbom);
        btn.setPosition(hudBackground.getWidth() - (btn.getWidth() + 10), 40);
        btn.setTag(WORLD_BTN_TAG);
        btn.setCullingEnabled(true);
        TextMenuItem worldBtnTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlack(), activity.getResources().getString(de.szut.splasher.R.string.world), vbom);
        worldBtnTxt.setPosition(btn.getScaleCenterX() - (worldBtnTxt.getWidth() / 2), btn.getScaleCenterY() - (worldBtnTxt.getHeight() / 2));
        btn.attachChild(worldBtnTxt);
        return btn;
    }

    private Sprite createHudInfectedView() {
        Sprite sprite = new Sprite(0, 0, this.resourcesManager.getHud_view_transp(), vbom);
        sprite.setPosition(10, 10);
        sprite.setCullingEnabled(true);
        Sprite icon = new Sprite(0, 0, this.resourcesManager.getInfectedIcon(), vbom);
        icon.setPosition(sprite.getWidth() - (sprite.getWidth() - 5), sprite.getScaleCenterY() - 10);
        selectedInfectedUserTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), "0", vbom);
        selectedInfectedUserTxt.setColor(Color.BLACK);
        selectedInfectedUserTxt.setPosition(sprite.getScaleCenterX() - (selectedInfectedUserTxt.getWidth() / 2), sprite.getScaleCenterY() - (selectedInfectedUserTxt.getHeight() / 2));
        sprite.attachChild(selectedInfectedUserTxt);
        sprite.attachChild(icon);
        return sprite;
    }

    private Sprite createHudControlledView() {
        Sprite sprite = new Sprite(0, 0, this.resourcesManager.getHud_view_transp(), vbom);
        sprite.setPosition(hudBackground.getWidth() - (sprite.getWidth() + 10), 10);
        sprite.setCullingEnabled(true);
        Sprite icon = new Sprite(0, 0, this.resourcesManager.getControlledIcon(), vbom);
        icon.setPosition(sprite.getWidth() - (sprite.getWidth() - 5), sprite.getScaleCenterY() - 10);
        selectedControlledUserTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), "0", vbom);
        selectedControlledUserTxt.setColor(Color.BLACK);
        selectedControlledUserTxt.setPosition(sprite.getScaleCenterX() - (selectedControlledUserTxt.getWidth() / 2), sprite.getScaleCenterY() - (selectedControlledUserTxt.getHeight() / 2));
        sprite.attachChild(selectedControlledUserTxt);
        sprite.attachChild(icon);
        return sprite;
    }

    private Sprite createHudCountryView() {
        Sprite sprite = new Sprite(0, 0, this.resourcesManager.getHud_view(), vbom);
        sprite.setPosition(300, 40);
        sprite.setCullingEnabled(true);
        selectedCountryTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontWhite(), activity.getResources().getString(de.szut.splasher.R.string.world), vbom);
        selectedCountryTxt.setColor(Color.WHITE);
        selectedCountryTxt.setPosition(sprite.getScaleCenterX() - (selectedCountryTxt.getWidth() / 2), sprite.getScaleCenterY() - (selectedCountryTxt.getHeight() / 2));
        sprite.attachChild(selectedCountryTxt);
        return sprite;
    }

    private Sprite createHudResearchView() {
        Sprite sprite = new Sprite(0, 0, this.resourcesManager.getHud_view_transp(), vbom);
        sprite.setPosition(300, 10);
        sprite.setCullingEnabled(true);
        Sprite icon = new Sprite(0, 0, resourcesManager.getResearchIcon(), vbom);
        icon.setPosition(sprite.getWidth() - (sprite.getWidth() - 5), sprite.getScaleCenterY() - 10);
        researchProgressTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), "0.00", vbom);
        researchProgressTxt.setColor(Color.BLACK);
        researchProgressTxt.setPosition(sprite.getScaleCenterX() - (researchProgressTxt.getWidth() / 2), sprite.getScaleCenterY() - (researchProgressTxt.getHeight() / 2));
        sprite.attachChild(icon);
        sprite.attachChild(researchProgressTxt);
        return sprite;
    }

    private void setCurrentSelectedCountryInHud(String countryName) {
        selectedCountryTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontWhite(), countryName, vbom);
        selectedCountryTxt.setPosition(hudCountryView.getScaleCenterX() - (selectedCountryTxt.getWidth() / 2), hudCountryView.getScaleCenterY() - (selectedCountryTxt.getHeight() / 2));
        hudCountryView.detachChildren();
        hudCountryView.attachChild(selectedCountryTxt);
    }

    private void setResearchProgressInHud(String totalResearchProcess) {
        hudResearchView.detachChild(researchProgressTxt);
        researchProgressTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), totalResearchProcess +" %", vbom);
        researchProgressTxt.setColor(Color.BLACK);
        researchProgressTxt.setPosition(hudResearchView.getScaleCenterX() - (researchProgressTxt.getWidth() / 2), hudResearchView.getScaleCenterY() - (researchProgressTxt.getHeight() / 2));
        hudResearchView.attachChild(researchProgressTxt);
    }

    private void setInfectedUserInHud() {
        String infectedUser = formatter.format(infectedUserOfCurrentCountry);
        hudInfectedView.detachChild(selectedInfectedUserTxt);
        selectedInfectedUserTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), infectedUser, vbom);
        selectedInfectedUserTxt.setColor(Color.BLACK);
        selectedInfectedUserTxt.setPosition(hudInfectedView.getScaleCenterX() - (selectedInfectedUserTxt.getWidth() / 2), hudInfectedView.getScaleCenterY() - (selectedInfectedUserTxt.getHeight() / 2));
        hudInfectedView.attachChild(selectedInfectedUserTxt);
    }

    private void setControlledUserInHud() {
        String controlledUser = formatter.format(controlledUserOfCurrentCountry);
        hudControlledView.detachChild(selectedControlledUserTxt);
        selectedControlledUserTxt = new TextMenuItem(0, resourcesManager.getGameMenuFontBlackSmall(), controlledUser, vbom);
        selectedControlledUserTxt.setColor(Color.BLACK);
        selectedControlledUserTxt.setPosition(hudControlledView.getScaleCenterX() - (selectedControlledUserTxt.getWidth() / 2), hudControlledView.getScaleCenterY() - (selectedControlledUserTxt.getHeight() / 2));
        hudControlledView.attachChild(selectedControlledUserTxt);
    }

    private void prepareZoomCamera() {
        this.zoomCamera = resourcesManager.getZoomCamera();
        this.zoomCamera.setZoomFactor(0.4f);
        this.zoomCamera.setBounds(0, 0, Settings.RESOLUTION_WIDTH, Settings.RESOLUTION_HEIGHT);
        this.zoomCamera.setBoundsEnabled(true);
    }

    private void resetZoomCamera() {
        this.zoomCamera.setZoomFactor(1.0f);
        this.zoomCamera.setBoundsEnabled(false);
        this.zoomCamera.setHUD(null);
    }

    public void setInfectedAndControlledUserfromSelectedCountry(Country selectedCountry) {
        this.infectedUserOfCurrentCountry = 0;
        this.controlledUserOfCurrentCountry = 0;
        HashMap<String, ArrayList<User>> countriesMap = logic.getAllUsersInCountriesMap();
        ArrayList<User> userOfInfectedCountry = null;
        if (selectedCountry != null) {
            for (String s : countriesMap.keySet()) {
                if (s.equals(selectedCountry.getName())) {
                    userOfInfectedCountry = countriesMap.get(s);
                }
            }
            if (userOfInfectedCountry != null) {
                for (User user : userOfInfectedCountry) {
                    infectedUserOfCurrentCountry += user.getInfectedUsers();
                    controlledUserOfCurrentCountry += user.getControlledUsers();
                }
            }
            setInfectedUserInHud();
            setControlledUserInHud();
        } else {
            updateGameHudViewForWorld();
        }
    }

    private Sprite genereateRedDot(ArrayList<String> countryPixel) {
        Random random = new Random();
        int ranNum = random.nextInt(countryPixel.size());
        String ranPixel = countryPixel.get(ranNum);
        StringTokenizer tokenizer = new StringTokenizer(ranPixel, ";");
        float x = Integer.parseInt(tokenizer.nextToken());
        float y = Integer.parseInt(tokenizer.nextToken());
        Sprite redDot = getRedDotFromPool();
        redDot.setPosition((x * factor_max), (y * factor_max));
        countryPixel.remove(ranNum);
        return redDot;
    }

    private Sprite getRedDotFromPool() {
        return infectedDotPool.obtainPoolItem();
    }

    private ButtonSprite getNewInfectionIconFromPool() {
        return newInfectionPool.obtainPoolItem();
    }

    @Override
    public void onPinchZoomStarted(PinchZoomDetector pPinchZoomDetector, TouchEvent pSceneTouchEvent) {
        this.pinchZoomFactor = this.zoomCamera.getZoomFactor();
    }


    @Override
    public void onPinchZoom(PinchZoomDetector pPinchZoomDetector, TouchEvent pTouchEvent, float pZoomFactor) {
        this.pinchZoomFactor *= pZoomFactor;
        if (pinchZoomFactor <= zoomMIN) {
            this.zoomCamera.setZoomFactor(zoomMIN);
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(0, 0, Settings.RESOLUTION_WIDTH, Settings.RESOLUTION_HEIGHT);
        } else if (pinchZoomFactor >= zoomMAX) {
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(-Settings.MAX_WIDTH * 0.5f, -Settings.MAX_HEIGHT * 0.5f, Settings.MAX_WIDTH, Settings.MAX_HEIGHT);
            this.zoomCamera.setZoomFactor(zoomMAX);
        } else {
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(-Settings.MAX_WIDTH * 0.5f, -Settings.MAX_HEIGHT * 0.5f, Settings.MAX_WIDTH, Settings.MAX_HEIGHT);
            this.zoomCamera.setZoomFactor(zoomMED);
        }
    }

    @Override
    public void onPinchZoomFinished(PinchZoomDetector pPinchZoomDetector, TouchEvent pTouchEvent, float pZoomFactor) {
        this.pinchZoomFactor *= pZoomFactor;
        if (pinchZoomFactor <= zoomMIN) {
            this.zoomCamera.setZoomFactor(zoomMIN);
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(0, 0, Settings.RESOLUTION_WIDTH, Settings.RESOLUTION_HEIGHT);
        } else if (pinchZoomFactor >= zoomMAX) {
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(-Settings.MAX_WIDTH * 0.5f, -Settings.MAX_HEIGHT * 0.5f, Settings.MAX_WIDTH, Settings.MAX_HEIGHT);
            this.zoomCamera.setZoomFactor(zoomMAX);
        } else {
            this.zoomCamera.setCenter(this.getScaleCenterX() + (this.resourcesManager.getGameRegion().getWidth() * 0.25f), this.getScaleCenterY() + (this.resourcesManager.getGameRegion().getHeight() * 0.25f));
            this.zoomCamera.setBounds(-Settings.MAX_WIDTH * 0.5f, -Settings.MAX_HEIGHT * 0.5f, Settings.MAX_WIDTH, Settings.MAX_HEIGHT);
            this.zoomCamera.setZoomFactor(zoomMED);
        }
    }

    @Override
    public void onScrollStarted(ScrollDetector pScrollDetector, int pPointerID, float pDistanceX, float pDistanceY) {
        this.unregisterTouchArea(gameMapClick);
    }

    @Override
    public void onScroll(ScrollDetector pScrollDetector, int pPointerID, float pDistanceX, float pDistanceY) {
        float zoomFactor = this.zoomCamera.getZoomFactor();
        this.zoomCamera.offsetCenter(-pDistanceX / zoomFactor, -pDistanceY / zoomFactor);
    }

    @Override
    public void onScrollFinished(ScrollDetector pScrollDetector, int pPointerID, float pDistanceX, float pDistanceY) {
        this.registerTouchArea(gameMapClick);
        this.zoomCamera.setHUD(gameHud);
    }

    @Override
    public boolean onSceneTouchEvent(Scene pScene, TouchEvent pSceneTouchEvent) {
        if (sceneIsTouchable) {
            if (timeIsRunning) {
                pauseTimer();
            }
            if (this.pinchZoomDetector != null) {
                this.pinchZoomDetector.onTouchEvent(pSceneTouchEvent);
                if (this.pinchZoomDetector.isZooming()) {
                    this.scrollDetector.setEnabled(false);
                } else {
                    if (pSceneTouchEvent.isActionDown()) {
                        this.scrollDetector.setEnabled(true);
                    }
                    this.scrollDetector.onTouchEvent(pSceneTouchEvent);
                }
            } else {
                this.scrollDetector.onTouchEvent(pSceneTouchEvent);
            }
        }
        if (timer != null &&timer.isPaused()) {
            reRunTimer();
        }
        return true;  //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
        switch (pButtonSprite.getTag()) {
            case VIRUS_BTN_TAG:
                if (GameScene.this.worldMenu.getVisibility() == View.GONE) {
                    this.abilityMenu.post(new Runnable() {
                        @Override
                        public void run() {
                            sceneIsTouchable = false;
                            if (timeIsRunning) {
                                pauseTimer();
                            }
                            GameScene.this.abilityMenu.setVisibility(View.VISIBLE);

                        }
                    });
                }
                break;
            case WORLD_BTN_TAG:
                if (GameScene.this.abilityMenu.getVisibility() == View.GONE) {
                    this.worldMenu.post(new Runnable() {
                        @Override
                        public void run() {
                            if (timeIsRunning) {
                                pauseTimer();
                            }
//                            Fragment f = tabManager.getCurrentFragment();
//                            if(f instanceof WorldTabFragment){
//                                ((WorldTabFragment)f).setValues();
//                            }
                            GameScene.this.worldMenu.setVisibility(View.VISIBLE);
                        }
                    });
                }
                break;
        }
    }

    public void reRunTimer() {
        timer.setPaused(false);
    }

    public void pauseTimer() {
        timer.setPaused(true);
    }

    public boolean isTimeIsRunning() {
        return timeIsRunning;
    }

    public void setSceneIsTouchable(boolean sceneIsTouchable) {
        this.sceneIsTouchable = sceneIsTouchable;
    }

    private void setupTimerHandler() {
        this.timer = new Timer(Settings.INTERVAL, new Timer.ITimerCallback() {
            @Override
            public void onTick() {
                logic.onCalculate();
            }
        });
        resourcesManager.getEngine().registerUpdateHandler(this.timer);
        timeIsRunning = true;
    }

    @Override
    public void onGameStart() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void onGameWon() {
        showWonDialog();
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void onGameLost() {
        showLostDialog();
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void onGameProgress() {
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void populateInfectedUser(Country infectedCountry) {
        ArrayList<String> countryPixel = countryPixeleMap.get(infectedCountry.getName());
        ArrayList<Sprite> infectedDotsInCountry = null;
        SpriteBatch spriteBatch = null;
        long totalUser = 0;
        long infectedUser = 0;
        if (countrieBatches.containsKey(infectedCountry.getName())) {
            spriteBatch = countrieBatches.get(infectedCountry.getName());
            infectedDotsInCountry = drawnInfectedDots.get(infectedCountry.getName());
            if (infectedDotsInCountry == null) {
                infectedDotsInCountry = new ArrayList<Sprite>();
            }
        }
        if (spriteBatch != null) {
            for (OperatingSystem os : infectedCountry.getOperatingSystems()) {
                totalUser += os.getUsers().getTotalUsers();
                infectedUser += os.getUsers().getInfectedUsers() + os.getUsers().getControlledUsers();
            }
            if (infectedUser >= (totalUser / countryPixel.size()) && infectedUser <= totalUser) {
                infectedDotsInCountry.add(genereateRedDot(countryPixel));
                for (Sprite dot : infectedDotsInCountry) {
                    spriteBatch.draw(dot);
                }
                spriteBatch.submit();
            }
            if (!drawnInfectedDots.containsKey(infectedCountry.getName())) {
                drawnInfectedDots.put(infectedCountry.getName(), infectedDotsInCountry);
            }
            if (gameMap.getChildByTag(infectedCountry.getColor()) != null) {
                gameMap.detachChild(spriteBatch);
            }
            if (!countrieBatches.containsKey(infectedCountry.getName())) {
                countrieBatches.put(infectedCountry.getName(), spriteBatch);
            }
            gameMap.attachChild(spriteBatch);
        }
    }

    @Override
    public void newCountryIsInfected(Country infectedCountry) {
        final ButtonSprite sprite = getNewInfectionIconFromPool();
        String centerPoint = countryCenterPoints.get(infectedCountry.getName());
        StringTokenizer tokenizer = new StringTokenizer(centerPoint, ";");
        float x = Float.valueOf(tokenizer.nextToken());
        float y = Float.valueOf(tokenizer.nextToken());
//        sprite.setTag((int) (x + y));
        sprite.setPosition((x * factor_max) - (sprite.getWidth() / 2), (y * factor_max) - (sprite.getHeight() / 2));
        sprite.setOnClickListener(new ButtonSprite.OnClickListener() {
            @Override
            public void onClick(ButtonSprite pButtonSprite, float pTouchAreaLocalX, float pTouchAreaLocalY) {
                GameScene.this.gameMap.detachChild(pButtonSprite);
                pButtonSprite.clearEntityModifiers();
            }
        });
        this.registerTouchArea(sprite);
        gameMap.attachChild(sprite);
        resourcesManager.getEngine().registerUpdateHandler(new TimerHandler(3f, new ITimerCallback() {
            @Override
            public void onTimePassed(TimerHandler pTimerHandler) {
                gameMap.detachChild(sprite);
                sprite.clearEntityModifiers();
            }
        }));

        //To change body of implemented methods use File | Settings | File Templates.
    }

    private void updateGameHudViewForCountry(Country country) {
        if (this.selectedCountry.getName().equals(country.getName())) {
            ArrayList<User> users = new ArrayList<User>();
            users.add(country.getOperatingSystems().getLinux().getUsers());
            users.add(country.getOperatingSystems().getWindows().getUsers());
            users.add(country.getOperatingSystems().getMac().getUsers());
            for (User user : users) {
                this.infectedUserOfCurrentCountry += user.getInfectedUsers();
                this.controlledUserOfCurrentCountry += user.getControlledUsers();
            }
            setInfectedUserInHud();
            setControlledUserInHud();
        }
    }

    private void updateGameHudViewForWorld() {
        HashMap<String, ArrayList<User>> countriesMap = logic.getAllUsersInCountriesMap();
        ArrayList<User> userWorld = new ArrayList<User>();
        for (String key : countriesMap.keySet()) {
            userWorld.addAll(countriesMap.get(key));
        }
        for (User user : userWorld) {
            infectedUserOfCurrentCountry += user.getInfectedUsers();
            controlledUserOfCurrentCountry += user.getControlledUsers();
        }
        setInfectedUserInHud();
        setControlledUserInHud();
    }

    @Override
    public void updateGameHudViewUser(Country country) {
        this.controlledUserOfCurrentCountry = 0;
        this.infectedUserOfCurrentCountry = 0;
        if (selectedCountry != null) {
            updateGameHudViewForCountry(country);
        } else {
            updateGameHudViewForWorld();

        }
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void updateGameHudViewResearch(String totalResearchProgress) {
        setResearchProgressInHud(totalResearchProgress);
    }

    @Override
    public void showResearchHasStartedDialog(final String osName) {
        resourcesManager.getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                AlertDialog.Builder builder = new AlertDialog.Builder(activity);
                builder.setTitle("Die Forschung nach einem Anti-Virus für " + osName + " hat begonnen");
                builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
                AlertDialog dialog = builder.create();
                dialog.show();

            }
        });

    }

    private void clearScene() {
        resourcesManager.getEngine().runOnUpdateThread(new Runnable() {
            @Override
            public void run() {
                GameScene.this.clearChildScene();
                GameScene.this.clearEntityModifiers();
                GameScene.this.clearUpdateHandlers();
                GameScene.this.clearTouchAreas();
            }
        });
    }

    private void exitGameScene() {
        if (timer != null) {
            timer = null;
        }
        this.clearScene();
        this.resourcesManager.getEngine().unregisterUpdateHandler(this.timer);
        resetZoomCamera();
        Logic.setInstance(null);
        if (pausedDialog.isVisible()) {
            pausedDialog.dismiss();
        }
        if (wonDialog.isVisible()) {
            wonDialog.dismiss();
        }
        if (lostDialog.isVisible()) {
            lostDialog.dismiss();
        }
        SceneManager.getInstance().disposeGameSecne();
    }

    private void saveCurrentGameState() {
        if (timeIsRunning) {
            pauseTimer();
        }
        storageHelper.saveGameState(this.logic);

    }

    @Override
    public void resumeToGame() {
        pausedDialog.dismiss();
        this.setSceneIsTouchable(true);
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void exitGame() {
        exitGameScene();
        //To change body of implemented methods use File | Settings | File Templates.
    }

    @Override
    public void saveAndExitGame() {
        saveCurrentGameState();
        exitGame();
        //To change body of implemented methods use File | Settings | File Templates.
    }
}
